

#ifndef X_LOGFILE_H
#define X_LOGFILE_H

#include <string>
#include <cstring>
#include <sys/types.h>  // for off_t
#include <sys/stat.h>
#include <unistd.h>
#include <mutex>
#include <memory>
#include <utility>
#include <atomic>

//针对文件操作进行基本的封装
class CLogFile
{
public:
    explicit CLogFile(std::string   filename, const bool flag = false, FILE* plogFile = nullptr) :
            m_logFileName(std::move(filename)), m_isRoll(flag), m_logFile(plogFile)
    {
        if (!m_logFileName.empty())
        {
            chmod(m_logFileName.c_str(), 0777);
            m_logFile = fopen(m_logFileName.c_str(), "aeb+");
            if (nullptr != m_logFile)
            {
                m_logFileNameBak = m_logFileName + ".1";
                //获取日志文件当前大小
                m_writtenBytes = getLogFileSize();
            }
        }
        else
        {
            fwrite("unopen file\n", strlen("unopen file\n"),1 , stdout);
            fflush(stdout);
        }
    }
    CLogFile()
    {
        if (!m_logFileName.empty())
        {
            chmod(m_logFileName.c_str(), 0777);
            m_logFile = fopen(m_logFileName.c_str(), "ab+");
        }
    }
    ~CLogFile()
    {
        if (nullptr != m_logFile)
        {
            fflush(m_logFile);
            fclose(m_logFile);
            m_logFile = nullptr;
        }
        if (m_isRoll)
        {
            unlink(m_logFileNameBak.c_str());
            ::rename(m_logFileName.c_str(), m_logFileNameBak.c_str());
        }
    }
    inline void setLogFileName(const std::string& filename)
    {
        m_logFileName = filename;
        m_logFileNameBak += filename + ".1";
    }
    void writeLog(const char* logmsg, int len);
    void flushLog();
    void rollLogFile();
    void setRollFlag(bool flag);
private:
    //获取日志文件大小
    long getLogFileSize();
private:
    std::string m_logFileName;
    std::atomic_bool m_isRoll{};
    std::string m_logFileNameBak;
    off_t m_writtenBytes{};
    //默认日志回滚大小为200M
    enum { DEFAULT_ROLL_SIZE = 800 * 1024 * 1024 };
    FILE* m_logFile{nullptr};
}; //end class CLogFile

#endif //X_LOGFILE_H
